package com.tencent.youtufacetrack;

import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by qingliang on 16/5/20.
 */
public class StatisticsUtils
{
    /**
     * getDeviceId
     * @param aContext context
     * @return String
     */
    public static String getDeviceUid(Context aContext)
    {
        // Get the device id.
        String strDeviceId = StatisticsUtils.getIMEI(aContext.getApplicationContext());

        String strMacAddr = StatisticsUtils.getMacAddr(aContext.getApplicationContext());
        final boolean bWithMac = !TextUtils.isEmpty(strMacAddr);
        if( bWithMac )
        {
            strMacAddr = strMacAddr.replaceAll(":", "");
        }

        // Compose the result.
        String strUid = StatisticsUtils.encryptUid(strDeviceId + (bWithMac ? strMacAddr : ""));

        return StatisticsUtils.toMD5(strUid);
    }

    public static String getMacAddr(Context aContext)
    {
        if(aContext == null) {
            return null;
        }
        // Permission: <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        // Get mac address.
        String strMacAddr = null;

        WifiManager pWifiMan = (WifiManager) aContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if(pWifiMan != null) {
            WifiInfo pWifiInfo = pWifiMan.getConnectionInfo();
            if(pWifiInfo != null) {
                strMacAddr = pWifiInfo.getMacAddress();
            }
        }

        return strMacAddr;
    }

    public static String getIMEI(Context aContext)
    {
        // Get the device id.
        String strDeviceId = Secure.getString(aContext.getContentResolver(), Secure.ANDROID_ID);

        // Some devices can not get id by ANDROID_ID indicator.
        if ( TextUtils.isEmpty(strDeviceId) )
        {
            // Try another way to retrieve device id.
            TelephonyManager pManager = (TelephonyManager) aContext.getApplicationContext().
                    getSystemService(Context.TELEPHONY_SERVICE);
            if(pManager != null) {

                strDeviceId = pManager.getDeviceId();
            }
        }

        return strDeviceId;
    }

    /**
     * toMD5
     * The version to match PHP version.
     * @param strVal string value
     * @return string
     */
    public static String toMD5(String strVal)
    {
        if( TextUtils.isEmpty(strVal) )
            return "";

        String strResult = "";
        try
        {
            MessageDigest pDigest = MessageDigest.getInstance("MD5");
            pDigest.reset();
            pDigest.update(strVal.getBytes());

            BigInteger hash = new BigInteger(1, pDigest.digest());
            strResult = hash.toString(16);
            while(strResult.length() < 32)
            {
                strResult = "0" + strResult;
            }
        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
            strResult = "";
        }

        return strResult;
    }

    /**
     * getChar
     * @param aByte
     * @param nPos
     * @return
     */
    private static char getChar(byte aByte, int nPos)
    {
        return (char) (aByte - StatisticsUtils.getOffset((nPos & 0x01)));
    }

    /**
     * getOffset
     * @param nVal
     * @return
     */
    private static byte getOffset(int nVal)
    {
        byte nByte = (byte) (0 == nVal ? 65 : 97);
        return nByte;
    }

    /**
     * encryptUid
     * @param strUid
     * @return
     */
    private static String encryptUid(String strUid)
    {
        if( TextUtils.isEmpty(strUid) )
            return "";

        StringBuilder pBuilder = new StringBuilder();
        final int nLength = strUid.length();
        for( int nIdx = 0; nIdx < nLength; nIdx++ )
        {
            final int nChar = strUid.charAt(nIdx);
            pBuilder.append(nChar + (nChar % nLength));
        }
        pBuilder.reverse();
        return pBuilder.toString();
    }

    /**
     * default constructor of StatisticsUtils
     */
    private StatisticsUtils()
    {
    }
}
